﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Security.Principal;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http.Controllers;
using System.Web.Mvc;
using System.Net.Http;

namespace Wicresoft.EKA.MVCExtensions
{
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
    public class PermissionAPIAttribute : System.Web.Http.AuthorizeAttribute
    {
        public bool IsPublic { get; set; }

        private string[] _rolesSplit = new string[0];

        private string[] _usersSplit = new string[0];

        protected override bool IsAuthorized(HttpActionContext actionContext)
        {
            IHttpController controller = actionContext.ControllerContext.Controller;
            BaseAPIController baseController = controller as BaseAPIController;

            if (null == baseController)
            {
                throw new InvalidOperationException("Controller must implement the BaseController");
            }
            baseController.OnBeforeAuthorize();

            if (IsPublic) return true;

            if (actionContext == null)
            {
                throw new ArgumentNullException("actionContext");
            }

            IPrincipal user = Thread.CurrentPrincipal;

            if (user == null || !user.Identity.IsAuthenticated)
            {
                return false;
            }

            _rolesSplit = PermissionAttribute.SplitString(Roles);
            _usersSplit = PermissionAttribute.SplitString(Users);

            if (_usersSplit.Length > 0 && !_usersSplit.Contains(user.Identity.Name, StringComparer.OrdinalIgnoreCase))
            {
                return false;
            }

            ICollection<String> baseRoles = baseController.Roles;

            if ((_rolesSplit.Length > 0 && !_rolesSplit.Any(o => baseRoles.Contains(o))))
            {
                return false;
            }

            return true;
        }

        protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
        {

            if (actionContext == null)
            {
                throw new ArgumentNullException("actionContext");
            }

            actionContext.Response = actionContext.ControllerContext.Request.
                CreateErrorResponse(HttpStatusCode.Forbidden, "RequestNotAuthorized");
        }

    }
}
